extends Node
class_name BuffManager

signal buff_added(data: BuffData)
signal buff_removed(data: BuffData)
signal buff_stack_changed(data: BuffData, new_stack: int)
signal buff_expired(data: BuffData)

var _active: Dictionary[String, BuffState] = {}
var _buff_count: int = 0

func add_buff(data: BuffData, user: Node = null) -> BuffState:
	if not data.is_valid():
		push_error("尝试添加无效的buff: " + data.get_buff_name())
		return null
		
	var state: BuffState
	if _active.has(data.get_buff_name()):
		state = _active[data.get_buff_name()]
		if state.can_stack():
			state.add_stack()
			emit_signal("buff_stack_changed", data, state.get_stacks())
		# 重置持续时间
		state.remaining = data.get_duration()
		print("灼烧buff已存在，叠加层数: ", state.get_stacks())
	else:
		# 对于EnemyHealthComponent，holder应该是敌人的根节点
		var holder = self.get_parent()
		if holder is EnemyHealthComponent:
			holder = holder.get_parent()
		state = BuffState.new(data, holder, user)
		_active[data.get_buff_name()] = state
		state._exec_script(data.get_buff_script(), "on_apply")
		_buff_count += 1
		emit_signal("buff_added", data)
		print("创建新的灼烧buff")
	return state

func remove_buff(id: String) -> void:
	if not _active.has(id): 
		return
	var state: BuffState = _active[id]
	state._exec_script(state.data.get_buff_script(), "on_remove")
	_active.erase(id)
	_buff_count -= 1
	emit_signal("buff_removed", state.data)

func has_buff(id: String) -> bool:
	return _active.has(id)

func get_buff_state(id: String) -> BuffState:
	return _active.get(id, null)

func clear_all() -> void:
	var buff_names = _active.keys()
	for id in buff_names:
		remove_buff(id)

func get_active_buffs() -> Array[BuffState]:
	return _active.values()

func get_buff_count() -> int:
	return _buff_count

func get_buff_names() -> Array[String]:
	return _active.keys()

## 获取特定类型的buff
func get_buffs_by_type(buff_type: String) -> Array[BuffState]:
	var result: Array[BuffState] = []
	for state in _active.values():
		if state.data.get_buff_name().contains(buff_type):
			result.append(state)
	return result

## 移除特定类型的buff
func remove_buffs_by_type(buff_type: String) -> void:
	var to_remove: Array[String] = []
	for id in _active.keys():
		if id.contains(buff_type):
			to_remove.append(id)
	for id in to_remove:
		remove_buff(id)

func _physics_process(delta: float) -> void:
	var to_remove: Array[String] = []
	for id: String in _active.keys():
		var state: BuffState = _active[id]
		state.advance(delta)
		if state.expired():
			to_remove.append(id)
			emit_signal("buff_expired", state.data)
	
	for id in to_remove:
		remove_buff(id)

